package com.sdses.weather.service;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sdses.weather.common.MappingResult;
import com.sdses.weather.config.WeatherProviderSchemaConfig;
import com.sdses.weather.config.cache.DynamicCacheable;
import com.sdses.weather.config.exception.BusinessException;
import com.sdses.weather.config.mapping.FieldInstructionCompiler;
import com.sdses.weather.factory.WeatherApiProvider;
import com.sdses.weather.factory.WeatherApiProviderRegistry;
import com.sdses.weather.model.RequestContext;
import com.sdses.weather.model.RequestContextHolder;
import com.sdses.weather.utils.HttpUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;


@Slf4j
@Service
@RequiredArgsConstructor
public class WeatherQueryCommonService {

//    @Autowired
//    private WeatherMappingFiled weatherMappingFiled;
    @Autowired
    private FieldInstructionCompiler weatherMappingFiled;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private WeatherApiProviderRegistry weatherApiProviderRegistry;
    @Autowired
    private WeatherProviderSchemaConfig weatherProviderSchemaConfig;

    @DynamicCacheable(
            cacheName = "weather_api_cache",
            key = "T(com.sdses.weather.model.RequestContextHolder).getCacheKey()",
            ttl = "T(com.sdses.weather.model.RequestContextHolder).getTtl()"  // 这个字段会被 DynamicExpiry 读取
    )
    public Object execute() {
        RequestContext context = RequestContextHolder.getContext();
        WeatherApiProvider weatherApiProvider = weatherApiProviderRegistry.getProvider(context.getProvider());

        return doExecuteApi(context, weatherApiProvider, json -> {
            try {

                //minutely、daily、alert、hourly、condition
                String dataType = context.getType().split("-")[0];

                WeatherProviderSchemaConfig.ProviderConfig providerConfig = weatherProviderSchemaConfig.getProvider(context.getProvider());

                // 2. 获取数据类型配置
                WeatherProviderSchemaConfig.DataTypeConfig typeConfig = WeatherProviderSchemaConfig.getDataTypeConfig(providerConfig, dataType);

                Class<?> aClass = context.getAClass();
                Class<?> contextClass = context.getContextClass();

                // 2. 执行映射（假设你的 mapper 支持传入 config）
                MappingResult<?, ?> mappingResult = weatherMappingFiled.mapDataListWithGlobal(
                        json,
                        context.getProvider(),
                        dataType,
                        aClass,
                        contextClass
                );

                Object contextInstance = mappingResult.getContext();
                if (contextInstance != null) {
                    List<?> dataList = (List<?>) mappingResult.getData();
                    if (dataList == null) {
                        dataList = Collections.emptyList();
                    }
                    // （使用配置的 targetField）
                    injectListField(contextInstance, dataList, typeConfig, aClass);
                }

                return contextInstance;
            } catch (Exception e) {
                log.error("映射预报数据失败", e);
                throw new BusinessException("数据解析失败: " + e.getMessage());
            }
        });
    }

    private <T> T doExecuteApi(
            RequestContext context,           // 通用上下文
            WeatherApiProvider provider,      // 厂商策略
            Function<String, T> resultMapper) {

        try {
            // 1. 构建请求配置
            String url = provider.buildUrl(context);
            String method = context.getMethod();
            Map<String, String> headers = provider.buildHeaders(context);
            Map<String, String> formParams = provider.buildFormParams(context);
            Map<String, String> jsonBody = provider.buildJsonBody(context);

            // 2. 发送请求
            HttpResponse response = HttpUtils.doPost(url, "", method, headers, jsonBody, formParams);
            String responseJson = EntityUtils.toString(response.getEntity());
            //hourly
//            String responseJson = "{\"code\":0,\"data\":{\"city\":{\"cityId\":284609,\"counname\":\"中国\",\"ianatimezone\":\"Asia/Shanghai\",\"name\":\"东城区\",\"pname\":\"北京市\",\"secondaryname\":\"北京市\",\"timezone\":\"8\"},\"sfc\":{\"banner\":\"未来一小时不会下雨\",\"confirmInfo\":{\"comfirmIcon\":255,\"comfirmIconDesc\":\"\",\"isConfirm\":0},\"isCorrect\":255,\"isFeedback\":0,\"notice\":\"未来一小时不会下雨\",\"percent\":[{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0},{\"dbz\":0,\"desc\":\"无雨\",\"icon\":-1,\"percent\":0.0}],\"rain\":0,\"rainLastTime\":0,\"sfCondition\":0,\"timestamp\":1754027327000}},\"msg\":\"success\",\"rc\":{\"c\":0,\"p\":\"success\"}}";
            //codition
//            String responseJson = "{\"code\":0,\"data\":{\"city\":{\"cityId\":1399,\"counname\":\"中国\",\"ianatimezone\":\"Asia/Shanghai\",\"name\":\"济南市\",\"pname\":\"山东省\",\"secondaryname\":\"山东省\",\"timezone\":\"8\"},\"condition\":{\"condition\":\"多云\",\"conditionId\":\"8\",\"humidity\":\"63\",\"icon\":\"1\",\"pressure\":\"982\",\"realFeel\":\"38\",\"sunRise\":\"2025-08-01 05:18:00\",\"sunSet\":\"2025-08-01 19:19:00\",\"temp\":\"33\",\"tips\":\"很闷热，感觉像在蒸桑拿。\",\"updatetime\":\"2025-08-01 14:25:08\",\"uvi\":\"5\",\"vis\":\"17300\",\"windDegrees\":\"45\",\"windDir\":\"东北风\",\"windLevel\":\"2\",\"windSpeed\":\"2.39\"}},\"msg\":\"success\",\"rc\":{\"c\":0,\"p\":\"success\"}}";
//daily
//            String responseJson ="{\"code\":0,\"data\":{\"city\":{\"cityId\":1399,\"counname\":\"中国\",\"ianatimezone\":\"Asia/Shanghai\",\"name\":\"济南市\",\"pname\":\"山东省\",\"secondaryname\":\"山东省\",\"timezone\":\"8\"},\"forecast\":[{\"conditionDay\":\"多云\",\"conditionIdDay\":\"1\",\"conditionIdNight\":\"31\",\"conditionNight\":\"多云\",\"humidity\":\"63\",\"moonphase\":\"WaxingCrescent\",\"moonrise\":\"2025-07-31 11:34:00\",\"moonset\":\"2025-07-31 22:30:00\",\"pop\":\"0\",\"predictDate\":\"2025-07-31\",\"qpf\":\"0.0\",\"sunrise\":\"2025-07-31 05:17:00\",\"sunset\":\"2025-07-31 19:20:00\",\"tempDay\":\"32\",\"tempNight\":\"25\",\"updatetime\":\"2025-07-31 22:00:00\",\"uvi\":\"8\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"多云\",\"conditionIdDay\":\"1\",\"conditionIdNight\":\"30\",\"conditionNight\":\"晴\",\"humidity\":\"74\",\"moonphase\":\"First\",\"moonrise\":\"2025-08-01 12:33:00\",\"moonset\":\"2025-08-01 22:57:00\",\"pop\":\"0\",\"predictDate\":\"2025-08-01\",\"qpf\":\"0.0\",\"sunrise\":\"2025-08-01 05:18:00\",\"sunset\":\"2025-08-01 19:19:00\",\"tempDay\":\"33\",\"tempNight\":\"26\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"5\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"小雨\",\"conditionIdDay\":\"7\",\"conditionIdNight\":\"30\",\"conditionNight\":\"晴\",\"humidity\":\"73\",\"moonphase\":\"WaxingGibbous\",\"moonrise\":\"2025-08-02 13:33:00\",\"moonset\":\"2025-08-02 23:27:00\",\"pop\":\"70\",\"predictDate\":\"2025-08-02\",\"qpf\":\"3.0\",\"sunrise\":\"2025-08-02 05:19:00\",\"sunset\":\"2025-08-02 19:18:00\",\"tempDay\":\"35\",\"tempNight\":\"26\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"6\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"晴\",\"conditionIdDay\":\"0\",\"conditionIdNight\":\"31\",\"conditionNight\":\"多云\",\"humidity\":\"69\",\"moonphase\":\"WaxingGibbous\",\"moonrise\":\"2025-08-03 14:34:00\",\"moonset\":\"2025-08-03 00:00:00\",\"pop\":\"0\",\"predictDate\":\"2025-08-03\",\"qpf\":\"0.0\",\"sunrise\":\"2025-08-03 05:20:00\",\"sunset\":\"2025-08-03 19:17:00\",\"tempDay\":\"35\",\"tempNight\":\"28\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"7\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"晴\",\"conditionIdDay\":\"0\",\"conditionIdNight\":\"31\",\"conditionNight\":\"多云\",\"humidity\":\"68\",\"moonphase\":\"WaxingGibbous\",\"moonrise\":\"2025-08-04 15:35:00\",\"moonset\":\"2025-08-04 00:03:00\",\"pop\":\"0\",\"predictDate\":\"2025-08-04\",\"qpf\":\"0.0\",\"sunrise\":\"2025-08-04 05:21:00\",\"sunset\":\"2025-08-04 19:16:00\",\"tempDay\":\"35\",\"tempNight\":\"28\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"6\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"中雨\",\"conditionIdDay\":\"8\",\"conditionIdNight\":\"9\",\"conditionNight\":\"大雨\",\"humidity\":\"72\",\"moonphase\":\"WaxingGibbous\",\"moonrise\":\"2025-08-05 16:33:00\",\"moonset\":\"2025-08-05 00:46:00\",\"pop\":\"50\",\"predictDate\":\"2025-08-05\",\"qpf\":\"28.0\",\"sunrise\":\"2025-08-05 05:21:00\",\"sunset\":\"2025-08-05 19:15:00\",\"tempDay\":\"36\",\"tempNight\":\"26\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"4\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"小雨\",\"conditionIdDay\":\"7\",\"conditionIdNight\":\"30\",\"conditionNight\":\"晴\",\"humidity\":\"68\",\"moonphase\":\"WaxingGibbous\",\"moonrise\":\"2025-08-06 17:25:00\",\"moonset\":\"2025-08-06 01:37:00\",\"pop\":\"80\",\"predictDate\":\"2025-08-06\",\"qpf\":\"3.0\",\"sunrise\":\"2025-08-06 05:22:00\",\"sunset\":\"2025-08-06 19:14:00\",\"tempDay\":\"33\",\"tempNight\":\"25\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"6\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"小雨\",\"conditionIdDay\":\"7\",\"conditionIdNight\":\"31\",\"conditionNight\":\"多云\",\"humidity\":\"58\",\"moonphase\":\"WaxingGibbous\",\"moonrise\":\"2025-08-07 18:11:00\",\"moonset\":\"2025-08-07 02:37:00\",\"pop\":\"60\",\"predictDate\":\"2025-08-07\",\"qpf\":\"3.0\",\"sunrise\":\"2025-08-07 05:23:00\",\"sunset\":\"2025-08-07 19:13:00\",\"tempDay\":\"31\",\"tempNight\":\"22\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"7\",\"windDegreesDay\":\"0\",\"windDegreesNight\":\"0\",\"windDirDay\":\"北风\",\"windDirNight\":\"北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"阴\",\"conditionIdDay\":\"2\",\"conditionIdNight\":\"2\",\"conditionNight\":\"阴\",\"humidity\":\"56\",\"moonphase\":\"WaxingGibbous\",\"moonrise\":\"2025-08-08 18:51:00\",\"moonset\":\"2025-08-08 03:42:00\",\"pop\":\"0\",\"predictDate\":\"2025-08-08\",\"qpf\":\"0.0\",\"sunrise\":\"2025-08-08 05:24:00\",\"sunset\":\"2025-08-08 19:12:00\",\"tempDay\":\"31\",\"tempNight\":\"24\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"6\",\"windDegreesDay\":\"90\",\"windDegreesNight\":\"180\",\"windDirDay\":\"东风\",\"windDirNight\":\"南风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"小雨\",\"conditionIdDay\":\"7\",\"conditionIdNight\":\"7\",\"conditionNight\":\"小雨\",\"humidity\":\"66\",\"moonphase\":\"Full\",\"moonrise\":\"2025-08-09 19:24:00\",\"moonset\":\"2025-08-09 04:51:00\",\"pop\":\"60\",\"predictDate\":\"2025-08-09\",\"qpf\":\"6.8\",\"sunrise\":\"2025-08-09 05:25:00\",\"sunset\":\"2025-08-09 19:11:00\",\"tempDay\":\"27\",\"tempNight\":\"22\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"3\",\"windDegreesDay\":\"180\",\"windDegreesNight\":\"315\",\"windDirDay\":\"南风\",\"windDirNight\":\"西北风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"小雨\",\"conditionIdDay\":\"7\",\"conditionIdNight\":\"30\",\"conditionNight\":\"晴\",\"humidity\":\"68\",\"moonphase\":\"WaningGibbous\",\"moonrise\":\"2025-08-10 19:54:00\",\"moonset\":\"2025-08-10 06:00:00\",\"pop\":\"60\",\"predictDate\":\"2025-08-10\",\"qpf\":\"2.6\",\"sunrise\":\"2025-08-10 05:25:00\",\"sunset\":\"2025-08-10 19:10:00\",\"tempDay\":\"27\",\"tempNight\":\"22\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"4\",\"windDegreesDay\":\"315\",\"windDegreesNight\":\"225\",\"windDirDay\":\"西北风\",\"windDirNight\":\"西南风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"晴\",\"conditionIdDay\":\"0\",\"conditionIdNight\":\"30\",\"conditionNight\":\"晴\",\"humidity\":\"71\",\"moonphase\":\"WaningGibbous\",\"moonrise\":\"2025-08-11 20:21:00\",\"moonset\":\"2025-08-11 07:10:00\",\"pop\":\"0\",\"predictDate\":\"2025-08-11\",\"qpf\":\"0.0\",\"sunrise\":\"2025-08-11 05:26:00\",\"sunset\":\"2025-08-11 19:08:00\",\"tempDay\":\"32\",\"tempNight\":\"23\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"6\",\"windDegreesDay\":\"270\",\"windDegreesNight\":\"135\",\"windDirDay\":\"西风\",\"windDirNight\":\"东南风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"晴\",\"conditionIdDay\":\"0\",\"conditionIdNight\":\"30\",\"conditionNight\":\"晴\",\"humidity\":\"60\",\"moonphase\":\"WaningGibbous\",\"moonrise\":\"2025-08-12 20:47:00\",\"moonset\":\"2025-08-12 08:18:00\",\"pop\":\"0\",\"predictDate\":\"2025-08-12\",\"qpf\":\"0.0\",\"sunrise\":\"2025-08-12 05:27:00\",\"sunset\":\"2025-08-12 19:07:00\",\"tempDay\":\"33\",\"tempNight\":\"25\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"6\",\"windDegreesDay\":\"135\",\"windDegreesNight\":\"135\",\"windDirDay\":\"东南风\",\"windDirNight\":\"东南风\",\"windLevelDay\":\"2\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"阴\",\"conditionIdDay\":\"2\",\"conditionIdNight\":\"7\",\"conditionNight\":\"小雨\",\"humidity\":\"55\",\"moonphase\":\"WaningGibbous\",\"moonrise\":\"2025-08-13 21:14:00\",\"moonset\":\"2025-08-13 09:27:00\",\"pop\":\"80\",\"predictDate\":\"2025-08-13\",\"qpf\":\"1.2\",\"sunrise\":\"2025-08-13 05:28:00\",\"sunset\":\"2025-08-13 19:06:00\",\"tempDay\":\"32\",\"tempNight\":\"23\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"5\",\"windDegreesDay\":\"135\",\"windDegreesNight\":\"135\",\"windDirDay\":\"东南风\",\"windDirNight\":\"东南风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"小雨\",\"conditionIdDay\":\"7\",\"conditionIdNight\":\"7\",\"conditionNight\":\"小雨\",\"humidity\":\"58\",\"moonphase\":\"WaningGibbous\",\"moonrise\":\"2025-08-14 21:43:00\",\"moonset\":\"2025-08-14 10:38:00\",\"pop\":\"60\",\"predictDate\":\"2025-08-14\",\"qpf\":\"2.1\",\"sunrise\":\"2025-08-14 05:29:00\",\"sunset\":\"2025-08-14 19:05:00\",\"tempDay\":\"26\",\"tempNight\":\"24\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"4\",\"windDegreesDay\":\"90\",\"windDegreesNight\":\"90\",\"windDirDay\":\"东风\",\"windDirNight\":\"东风\",\"windLevelDay\":\"1\",\"windLevelNight\":\"2\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"},{\"conditionDay\":\"小雨\",\"conditionIdDay\":\"7\",\"conditionIdNight\":\"2\",\"conditionNight\":\"阴\",\"humidity\":\"58\",\"moonphase\":\"WaningGibbous\",\"moonrise\":\"2025-08-15 22:16:00\",\"moonset\":\"2025-08-15 11:50:00\",\"pop\":\"80\",\"predictDate\":\"2025-08-15\",\"qpf\":\"3.0\",\"sunrise\":\"2025-08-15 05:30:00\",\"sunset\":\"2025-08-15 19:04:00\",\"tempDay\":\"32\",\"tempNight\":\"26\",\"updatetime\":\"2025-08-01 13:00:00\",\"uvi\":\"6\",\"windDegreesDay\":\"135\",\"windDegreesNight\":\"135\",\"windDirDay\":\"东南风\",\"windDirNight\":\"东南风\",\"windLevelDay\":\"2\",\"windLevelNight\":\"1\",\"windSpeedDay\":\"2.4\",\"windSpeedNight\":\"2.4\"}]},\"msg\":\"success\",\"rc\":{\"c\":0,\"p\":\"success\"}}";
//            String responseJson = "{\"code\":0,\"data\":{\"city\":{\"cityId\":1399,\"counname\":\"中国\",\"ianatimezone\":\"Asia/Shanghai\",\"name\":\"济南市\",\"pname\":\"山东省\",\"secondaryname\":\"山东省\",\"timezone\":\"8\"}},\"msg\":\"success\",\"rc\":{\"c\":0,\"p\":\"success\"}}";
            // 3. 检查错误
            JsonNode rootNode = objectMapper.readTree(responseJson);
            provider.checkResponse(rootNode);

            // 4. 映射结果
            return resultMapper.apply(responseJson);

        } catch (BusinessException e) {
            log.warn("天气API业务错误 [{}]: {}", provider.getClass().getSimpleName(), e.getMessage());
            throw new BusinessException(e.getCode(), e.getMsg());
        } catch (Exception e) {
            log.error("天气API请求失败 [{}]: {}", provider.getClass().getSimpleName(), e.getMessage(), e);
            throw new RuntimeException("天气API请求失败", e);
        }
    }

    /**
     * 将 dataList 注入到 target 对象的 list 字段中
     * 优先使用配置中的 targetListField，否则回退到命名约定
     */
    private void injectListField(
            Object target,
            List<?> dataList,
            WeatherProviderSchemaConfig.DataTypeConfig typeConfig, Class<?> aClass
    ) {
        try {

            if (CollUtil.isEmpty(dataList)) {
                return;
            }

            Class<?> targetClass = target.getClass();
            String targetField = typeConfig.getTargetField();

            Field field = ReflectionUtils.findField(targetClass, targetField);
            if (field == null) {
                throw new BusinessException("找不到字段 '" + targetField + "' in " + targetClass.getSimpleName());
            }

            Class<?> fieldType = field.getType();
            if (typeConfig.isArrayFlag()) {
                // 如果配置说这是个 List 字段
                if (!List.class.isAssignableFrom(fieldType)) {
                    throw new BusinessException("字段 '" + targetField + "' 应为 List 类型，但实际是 " + fieldType.getSimpleName());
                }
            } else {
                // 如果是普通对象字段，确保它能接受 dataList（比如是 DTO）
                // 这里可以加逻辑：比如 dataList.size() == 1 才能注入到单个对象
                if (dataList.size() > 1) {
                    throw new BusinessException("无法将 " + dataList.size() + " 个元素注入非列表字段 '" + targetField + "'");
                }
            }

            ReflectionUtils.makeAccessible(field);

            Object valueToSet = typeConfig.isArrayFlag() ? dataList : (dataList.isEmpty() ? aClass.newInstance() : dataList.get(0));
            field.set(target, valueToSet);

            log.debug("已将 {} 条数据注入 {}.{}", dataList.size(), targetClass.getSimpleName(), targetField);

        } catch (Exception e) {
            log.error("注入列表字段失败", e);
            throw new BusinessException("无法设置预报数据: " + e.getMessage());
        }
    }
}